package com.ikingtech.platform.service.system.user.service;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ikingtech.framework.sdk.department.api.DeptUserApi;
import com.ikingtech.framework.sdk.department.model.DeptManagerDTO;
import com.ikingtech.framework.sdk.department.model.DeptUserDTO;
import com.ikingtech.framework.sdk.utils.Tools;
import com.ikingtech.platform.service.system.user.entity.UserDO;
import com.ikingtech.platform.service.system.user.entity.UserDeptDO;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author tie yan
 */
@RequiredArgsConstructor
public class DeptUserService implements DeptUserApi {

    private final UserRepository service;

    private final UserDeptRepository userDeptService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void moveUser(String parentId, List<String> deptIds) {
        if (Tools.Coll.isBlank(deptIds)) {
            return;
        }
        List<String> userIds = this.userDeptService.listUserIdByDeptIds(deptIds);
        if (Tools.Coll.isBlank(userIds)) {
            return;
        }
        List<String> existUserIds = this.userDeptService.listUserIdByDeptId(parentId);
        if (Tools.Coll.isBlank(userIds)) {
            return;
        }
        this.userDeptService.saveBatch(Tools.Coll.convertList(userIds, userId -> !existUserIds.contains(userId), id -> {
            UserDeptDO entity = new UserDeptDO();
            entity.setId(Tools.Id.uuid());
            entity.setUserId(id);
            entity.setDeptId(parentId);
            return entity;
        }));

        this.userDeptService.remove(Wrappers.<UserDeptDO>lambdaQuery().in(UserDeptDO::getDeptId, deptIds));
    }

    @Override
    public DeptManagerDTO loadManager(String userId) {
        UserDO entity = this.service.getById(userId);
        if (null == entity) {
            return null;
        }
        DeptManagerDTO manager = new DeptManagerDTO();
        manager.setUserId(entity.getId());
        manager.setUserName(entity.getName());
        manager.setUserAvatar(entity.getAvatar());
        return manager;
    }

    @Override
    public List<DeptManagerDTO> loadManagers(List<String> userIds) {
        if (Tools.Coll.isBlank(userIds)) {
            return new ArrayList<>();
        }
        List<UserDO> entities = this.service.listByIds(userIds);
        if (Tools.Coll.isBlank(entities)) {
            return new ArrayList<>();
        }
        return Tools.Coll.convertList(entities, entity -> {
            DeptManagerDTO manager = new DeptManagerDTO();
            manager.setUserId(entity.getId());
            manager.setUserName(entity.getName());
            manager.setUserAvatar(entity.getAvatar());
            return manager;
        });
    }

    @Override
    public Map<String, Integer> getUserCount(List<String> deptIds) {
        if (Tools.Coll.isBlank(deptIds)) {
            return new HashMap<>();
        }
        List<UserDeptDO> userDeptEntities = this.userDeptService.listByDeptIds(deptIds);
        Map<String, List<UserDeptDO>> userDeptMap = Tools.Coll.convertGroup(userDeptEntities, UserDeptDO::getDeptId);

        Map<String, Integer> result = new HashMap<>(userDeptMap.size());
        userDeptMap.forEach((deptId, entities) -> result.put(deptId, entities.size()));
        return result;
    }

    @Override
    public List<DeptUserDTO> queryDeptUsersByUserIds(List<String> userIds) {
        List<UserDeptDO> list = this.userDeptService.list(Wrappers.<UserDeptDO>lambdaQuery().in(UserDeptDO::getUserId, userIds));
        return Tools.Coll.convertList(list, entity -> Tools.Bean.copy(entity, DeptUserDTO.class));

    }
}
